package com.rtos.vo.memory;

import com.rtos.model.memory.MAT;
import com.rtos.model.memory.MATNode;
import com.rtos.model.memory.MemoryDispatcher;
import com.rtos.model.memory.SystemMemory;
import com.rtos.model.process.PCB;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import lombok.extern.java.Log;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @Author: biubiu0002
 * @Date: 2021-10-17 9:23
 **/
@Log
public class MemoryPaneVO {
    private static double paneLayoutX;
    private static double paneLayoutY;
    private static double paneHeight;
    private static double paneWidth;
    private static List<PCB> pcbList = SystemMemory.getPCBList();
    private static ObservableList<MATNode> observableMATNodeList = MemoryDispatcher.getObservableMATNodeList();

    private static Map<MATNode,MemoryRectangle> memoryRectangles = new HashMap<>();

    private static List<MATNode> matList=MAT.getMATList();

    public static void setMemoryPane(Pane memoryPane){
        paneLayoutX = memoryPane.getLayoutX();
        paneLayoutY = memoryPane.getLayoutY();
        paneHeight = memoryPane.getPrefHeight();
        paneWidth = memoryPane.getPrefWidth();

        /**
         * 设置监听器 更新UI
         */
        observableMATNodeList.addListener((ListChangeListener<MATNode>) change->{
            while(change.next()){
                if(change.wasUpdated()){
//                    System.out.println("observableMATList 更新了一个元素");
                }
                else if(change.wasAdded()){
                    List<? extends MATNode> addedSubList = change.getAddedSubList();
                    MATNode matNode = addedSubList.get(0);
                    //双重检查，防止线程错误
                    if(matList.contains(matNode)){
                        log.info("新增了一个进程：" + matNode);
                        int pid = matNode.getPID();
                        if(pid==-1){
                            break;
                        }
                        int address = matNode.getAddress().get();
                        int size = matNode.getSize();
                        MemoryRectangle memoryRectangle = new MemoryRectangle(paneLayoutX + address,paneLayoutY, size, paneHeight, pid);
                        AnchorPane anchorPane = (AnchorPane) memoryPane.getParent();
                        ObservableList<Node> children = anchorPane.getChildren();
                        /**
                         * Platform.runLater()获得JavaFX Thread 并在该线程中执行任务
                         * 只能在JavaFX Thread中 处理
                         * 不然会报错
                         */
                        Platform.runLater(()->{
                            children.add(memoryRectangle);
                            memoryRectangles.put(matNode,memoryRectangle);

                        });
                    }

                }
                else if(change.wasRemoved()){
                    List<? extends MATNode> removed = change.getRemoved();
                    MATNode matNode = removed.get(0);
                    int pid = matNode.getPID();
                    if(pid==-1){
                        break;
                    }

                    AnchorPane anchorPane = (AnchorPane) memoryPane.getParent();
                    ObservableList<Node> children = anchorPane.getChildren();

                    MemoryRectangle memoryRectangle = memoryRectangles.get(matNode);
                    memoryRectangles.remove(matNode);

                    Platform.runLater(()->{
                        /**
                         * Platform.runLater()获得JavaFX Thread 并在该线程中执行任务
                         * 只能在JavaFX Thread中 处理
                         * 不然会报错
                         */
                        children.remove(memoryRectangle);
                    });
                }
                else{
                }
            }
        });


    }

}
